package  com.laboratory.Process;

import java.util.ArrayList;
import java.util.List;

/**
 *  获得线程的返回结果
 * 如果我们需要一个耗时任务在执行完之后给予返回值，应该怎么做呢?
 * 第一种方法：在 Runnable 的实现类中设置一个变量 V，在 run 方法中将其改变为我们期待的结果，然后通过一个 getV() 方法将这个变量返回。
 * 第二种方法：使用 Callable<V> 和 FutureTask<V> 
 * Thread.join的作用是等待线程结束，这个作用可以产生很多特定的场景。 
 *	1）A线程中调用B线程的join方法，那么A线程需要等待B线程执行完成后才能完成 
 *	2）主线程中依次调用A线程的join方法，B线程的join方法，可以保证A，B线程顺序执行； 
 *	主线程进入等待状态，子线程在运行，子线程运行完成后会通知主线程继续运行，
 *	或者join也可以设置主线程的等待时间，当主线程等待超时时，即使子线程没有运行完，主线程也会开始继续执行。
 *  t.join()方法阻塞调用此方法的线程(calling thread)，直到线程t完成，此线程再继续
 * @author admin
 *
 */
public class RunnableTest  {


	public static void main(String[] args) {
		System.out.println("使用 Runnable 获得返回结果：");
		
        List<Thread> workers = new ArrayList<Thread>(10);
        List<AccumRunnable> tasks = new ArrayList<AccumRunnable>(10);
		
        for(int i = 0; i < 10; i++){
            AccumRunnable task = new RunnableTest().new AccumRunnable(i * 10 + 1, (i + 1) * 10);
            Thread worker = new Thread(task, "慢速累加器线程" + i);

            tasks.add(task);
            workers.add(worker);
            
            worker.start();        	
        }
        int total = 0;
        for (int i = 0, s = workers.size(); i < s; i++) {
            try {
				workers.get(i).join(100);//join的作用是等待线程结束
			} catch (InterruptedException e) {
				e.printStackTrace();
			}  // 等待线程执行完毕
            total += tasks.get(i).getResult();
        }

        System.out.println("\n累加的结果: " + total);
		

	}
	//累加器线程 - runnable实现类
	class AccumRunnable implements Runnable{

        private final int begin;
        private final int end;

        private int result;

        public AccumRunnable(int begin, int end) {
            this.begin = begin;
            this.end = end;
        }
		@Override
		public void run() {
			long starttime = System.currentTimeMillis();
			result = 0;
            try {
                for (int i = begin; i <= end; i++) {
                    result += i;
                    Thread.sleep(2000);
                }
            } catch (Exception ex) {
                ex.printStackTrace(System.err);
            }
            System.out.printf("(%s) - 运行结束，结果为 %d， 运行时间为 %s\n",Thread.currentThread().getName(), result, System.currentTimeMillis()-starttime);
		}
        public int getResult() {
            return result;
        }
	}
	

}
